package com.itrh.base.service.impl;

import com.itrh.auth.domain.Permission;
import com.itrh.auth.mapper.PermissionMapper;
import com.itrh.base.annotation.AuthPermission;
import com.itrh.base.service.IPermissionScanService;
import com.itrh.org.util.ScanUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.util.List;

/**
 * ClassName: IPermissionScanServiceImpl
 *
 * @author XHU_WHY
 * @version V1.0
 * @since 2024/4/7 17:05
 */
@Slf4j
@Service
public class IPermissionScanServiceImpl implements IPermissionScanService {

    @Value("${scan.package-path}")
    private String packagePath;
    @Value("${scan.enable}")
    private Boolean enable;
    @Resource
    private PermissionMapper permissionMapper;

    @Override
    public void scan() {
        if (!enable) return;
        List<Class<?>> classList = ScanUtil.scan(packagePath);
        classList.forEach(clazz -> {
            // 获取类上面的注解
            AuthPermission parentPermission = clazz.getAnnotation(AuthPermission.class);
            if (parentPermission != null) {
                Permission parent = new Permission();
                parent.setName(parentPermission.name());
                parent.setDescs(parentPermission.desc());
                // 获取RequestMapping注解
                RequestMapping requestMapping = clazz.getAnnotation(RequestMapping.class);
                if (requestMapping != null) {
                    parent.setUrl(requestMapping.value()[0]);
                }
                parent.setSn(clazz.getSimpleName());
                // 从数据库查询该权限是否存在
                Permission parentInDb = permissionMapper.selectBySn(parent.getSn());
                if (parentInDb == null) {
                    // 如果不存在，则插入
                    permissionMapper.insert(parent);
                } else {
                    // 如果存在，则更新
                    parent.setId(parentInDb.getId());
                    permissionMapper.update(parent);
                }
                // 获取类里面的方法
                Method[] methods = clazz.getMethods();
                for (Method method : methods) {
                    // 获取方法上面的注解
                    AuthPermission childPermission = method.getAnnotation(AuthPermission.class);
                    if (childPermission != null) {
                        Permission child = new Permission();
                        child.setName(childPermission.name());
                        child.setDescs(childPermission.desc());
                        child.setSn(clazz.getSimpleName() + ":" + method.getName());
                        child.setParentId(parent.getId());
                        child.setUrl(parent.getUrl() + getUrl(method));
                        // 从数据库查询该权限是否存在
                        Permission childInDb = permissionMapper.selectBySn(child.getSn());
                        if (childInDb == null) {
                            // 如果不存在，则插入
                            permissionMapper.insert(child);
                        } else {
                            // 如果存在，则更新
                            child.setId(childInDb.getId());
                            permissionMapper.update(child);
                        }
                    }
                }
            }
        });
    }

    public String getUrl(Method method) {
        RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);
        if (requestMapping != null && requestMapping.value().length > 0) {
            return requestMapping.value()[0];
        }
        GetMapping getMapping = method.getAnnotation(GetMapping.class);
        if (getMapping != null && getMapping.value().length > 0) {
            return getMapping.value()[0];
        }
        PostMapping postMapping = method.getAnnotation(PostMapping.class);
        if (postMapping != null && postMapping.value().length > 0) {
            return postMapping.value()[0];
        }
        PutMapping putMapping = method.getAnnotation(PutMapping.class);
        if (putMapping != null && putMapping.value().length > 0) {
            return putMapping.value()[0];
        }
        DeleteMapping deleteMapping = method.getAnnotation(DeleteMapping.class);
        if (deleteMapping != null && deleteMapping.value().length > 0) {
            return deleteMapping.value()[0];
        }
        PatchMapping patchMapping = method.getAnnotation(PatchMapping.class);
        if (patchMapping != null && patchMapping.value().length > 0) {
            return patchMapping.value()[0];
        }
        return "";
    }
}
